package com.deliveryservicesystem.presentation.desktop.addpanel;

import com.deliveryservicesystem.app.exceptions.OutputError;
import com.deliveryservicesystem.app.exceptions.PreexistingEntityException;
import com.deliveryservicesystem.app.factory.AppFactory;
import com.deliveryservicesystem.app.util.AppUtils;
import com.deliveryservicesystem.app.validation.RouteValidator;
import com.deliveryservicesystem.app.validation.ValidationUtil;
import com.deliveryservicesystem.dataaccess.PersistenceDbManager;
import com.deliveryservicesystem.model.Delivery;
import com.deliveryservicesystem.model.Route;
import com.deliveryservicesystem.presentation.desktop.InfoLableChangeHandler;
import com.deliveryservicesystem.presentation.desktop.MatchDialog;
import com.deliveryservicesystem.service.crud.impl.RouteCrudServiceImpl;
import com.jgoodies.validation.ValidationResult;
import com.jgoodies.validation.view.ValidationComponentUtils;
import com.jgoodies.validation.view.ValidationResultViewFactory;
import java.awt.Component;
import java.awt.KeyboardFocusManager;
import java.sql.SQLException;
import java.util.HashMap;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JList;
import javax.swing.JOptionPane;

/**
 * File Name: AddEditRoutePanel.java
 * Version:
 * Description:
 * Package: com.deliveryservicesystem.presentation.desktop.addpanel
 * Author: Lance
 * Date: Jun 27, 2012
 * Editor:
 */
public class AddEditRouteDialog extends javax.swing.JDialog
{

    private static final long serialVersionUID = 1L;
    private RouteCrudServiceImpl routeCrudService;
    private Route routeFromDb;
    private PersistenceDbManager dbManager;

    public AddEditRouteDialog(java.awt.Frame parent, boolean modal, HashMap<String, String> values)
    {
        super(parent, modal);
        dbManager = PersistenceDbManager.getInstance();
        initComponents();
        cbDeliveryNo.setSelectedIndex(-1);
        routeCrudService = new RouteCrudServiceImpl();
        if (!values.isEmpty())
        {
            cbDeliveryNo.setSelectedItem(new Delivery(Integer.parseInt(values.get("DELIVERY NUMBER"))));
            lblRouteNo.setText(values.get("ROUTE NUMBER"));
            txtMainRoute.setText(values.get("MAIN ROUTE"));
            routeFromDb = routeCrudService.findById(Integer.parseInt(values.get("ROUTE NUMBER")));
        }

        ValidationComponentUtils.setInputHint(txtMainRoute, "Enter the main route");
        ValidationComponentUtils.setInputHint(cbDeliveryNo, "Select a delivery number");

        KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(new InfoLableChangeHandler(lblInfo));
    }

    /**
     * This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        entityManager = dbManager.getEntityManager();
        deliveryQuery = java.beans.Beans.isDesignTime() ? null : entityManager.createQuery("SELECT d FROM Delivery d");
        deliveryList = java.beans.Beans.isDesignTime() ? java.util.Collections.emptyList() : deliveryQuery.getResultList();
        lblRouteNo = new javax.swing.JLabel();
        txtMainRoute = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        btnMatchDelivery = new javax.swing.JButton();
        lblInfo = new javax.swing.JLabel();
        cbDeliveryNo = new javax.swing.JComboBox();
        btnCancel = new javax.swing.JButton();
        lblValidationErrors = new javax.swing.JLabel();
        lblValidationErrors.setVisible(false);
        jLabel5 = new javax.swing.JLabel();
        btnOk = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        jSeparator2 = new javax.swing.JSeparator();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        lblRouteNo.setText("New Number is Generated");

        jLabel1.setText("Route Number");

        jLabel6.setText("Delivery Number");

        btnMatchDelivery.setText("Match");
        btnMatchDelivery.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnMatchDeliveryActionPerformed(evt);
            }
        });

        lblInfo.setIcon(ValidationResultViewFactory.getInfoIcon());
        lblInfo.setText("Info Lable");

        cbDeliveryNo.setRenderer(new DefaultListCellRenderer()
            {

                @Override
                public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
                {
                    super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                    if (value instanceof Delivery)
                    {
                        Delivery delivery = (Delivery) value;
                        setText(delivery.getDeliveryNo().toString());
                    }
                    return this;
                }
            });

            org.jdesktop.swingbinding.JComboBoxBinding jComboBoxBinding = org.jdesktop.swingbinding.SwingBindings.createJComboBoxBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, deliveryList, cbDeliveryNo, "delivery");
            bindingGroup.addBinding(jComboBoxBinding);
            org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, deliveryList, org.jdesktop.beansbinding.ObjectProperty.create(), cbDeliveryNo, org.jdesktop.beansbinding.BeanProperty.create("selectedItem"), "deliveryNo");
            bindingGroup.addBinding(binding);

            btnCancel.setText("Cancel");
            btnCancel.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    btnCancelActionPerformed(evt);
                }
            });

            lblValidationErrors.setIcon(ValidationResultViewFactory.getCheckIcon());
            lblValidationErrors.setText("Validation Errors");

            jLabel5.setText("Main Route");

            btnOk.setText("OK");
            btnOk.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    btnOkActionPerformed(evt);
                }
            });

            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jSeparator1, javax.swing.GroupLayout.DEFAULT_SIZE, 369, Short.MAX_VALUE)
                .addComponent(jSeparator2, javax.swing.GroupLayout.DEFAULT_SIZE, 369, Short.MAX_VALUE)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                            .addGap(0, 0, Short.MAX_VALUE)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(lblInfo, javax.swing.GroupLayout.Alignment.TRAILING)
                                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                    .addComponent(btnOk, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(btnCancel))))
                        .addGroup(layout.createSequentialGroup()
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(layout.createSequentialGroup()
                                    .addComponent(jLabel1)
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(lblRouteNo))
                                .addComponent(lblValidationErrors)
                                .addGroup(layout.createSequentialGroup()
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(jLabel5)
                                        .addComponent(jLabel6))
                                    .addGap(37, 37, 37)
                                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addComponent(txtMainRoute)
                                        .addComponent(cbDeliveryNo, 0, 104, Short.MAX_VALUE))
                                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(btnMatchDelivery)))
                            .addGap(0, 0, Short.MAX_VALUE)))
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel1)
                        .addComponent(lblRouteNo))
                    .addGap(7, 7, 7)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel5)
                        .addComponent(txtMainRoute, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel6)
                        .addComponent(cbDeliveryNo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(btnMatchDelivery))
                    .addGap(18, 18, 18)
                    .addComponent(lblValidationErrors)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 54, Short.MAX_VALUE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(btnCancel)
                        .addComponent(btnOk))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(lblInfo)
                    .addContainerGap())
            );

            bindingGroup.bind();

            pack();
        }// </editor-fold>//GEN-END:initComponents

    private void btnMatchDeliveryActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnMatchDeliveryActionPerformed
    {//GEN-HEADEREND:event_btnMatchDeliveryActionPerformed
        try
        {
            MatchDialog frame = new MatchDialog(null, true, "BEGIN ? := GET_DATA.DELIVERIES; END;");
            AppUtils.locateOnScreenCenter(frame);
            frame.setVisible(true);
            cbDeliveryNo.setSelectedItem(new Delivery(frame.getReturnStatus()));
        }
        catch (SQLException ex)
        {
            OutputError.toLog(ex);
            OutputError.toUser(ex);
        }
    }//GEN-LAST:event_btnMatchDeliveryActionPerformed

    private void btnCancelActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnCancelActionPerformed
    {//GEN-HEADEREND:event_btnCancelActionPerformed
        if (AppUtils.askExitConfirm() == JOptionPane.YES_OPTION)
        {
            this.dispose();
        }
    }//GEN-LAST:event_btnCancelActionPerformed

    private void btnOkActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_btnOkActionPerformed
    {//GEN-HEADEREND:event_btnOkActionPerformed
        RouteValidator validator = new RouteValidator(txtMainRoute.getText(), cbDeliveryNo.getSelectedItem());
        ValidationResult validationResult = validator.validate(new ValidationResult());
        ValidationUtil.displayErrorsToLable(validationResult, lblValidationErrors);

        if (validationResult.isEmpty())
        {
            String mainRoute = txtMainRoute.getText();
            String routeNo = lblRouteNo.getText();
            Delivery delivery = (Delivery) cbDeliveryNo.getSelectedItem();

            Route route = AppFactory.createRoute(routeNo, mainRoute, delivery);

            int askUserQuestion = AppUtils.askUserQuestion(this, "Add/Edit the following?\n" + route, "Add/Edit", JOptionPane.YES_NO_CANCEL_OPTION);

            if (askUserQuestion == JOptionPane.YES_OPTION)
            {
                try
                {
                    if (route.getRouteNo() == null)
                    {
                        routeCrudService.create(route);
                        AppUtils.showUserMessage(this, "Added the following:\n" + route, "Add/Edit", JOptionPane.INFORMATION_MESSAGE);
                    }
                    else
                    {
                        AppFactory.createUpdatedProduct(route, routeFromDb);
                        routeCrudService.edit(routeFromDb);
                        AppUtils.showUserMessage(this, "Updated the following:\n" + route, "Add/Edit", JOptionPane.INFORMATION_MESSAGE);
                    }
                    this.dispose();
                }
                catch (PreexistingEntityException ex)
                {
                    OutputError.toLog(ex);
                    OutputError.toUser(ex);
                }
                catch (Exception ex)
                {
                    OutputError.toLog(ex);
                    OutputError.toUser(ex);
                }
            }
        }
    }//GEN-LAST:event_btnOkActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCancel;
    private javax.swing.JButton btnMatchDelivery;
    private javax.swing.JButton btnOk;
    private javax.swing.JComboBox cbDeliveryNo;
    private java.util.List<com.deliveryservicesystem.model.Delivery> deliveryList;
    private javax.persistence.Query deliveryQuery;
    private javax.persistence.EntityManager entityManager;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JLabel lblInfo;
    private javax.swing.JLabel lblRouteNo;
    private javax.swing.JLabel lblValidationErrors;
    private javax.swing.JTextField txtMainRoute;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables
}
